package com.jcfk.system.service;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.interfaces.Claim;
import com.jcfk.common.core.security.JwtUtil;
import com.jcfk.common.security.constant.SecurityConstants;
import com.jcfk.common.web.domain.LoginInfo;
import com.jcfk.common.websocket.model.JcfkSocketSession;
import com.jcfk.common.websocket.model.SocketMessage;
import com.jcfk.common.websocket.service.BaseSocketService;
import com.jcfk.system.domain.model.WebSocketMessageUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * web用户消息管理 服务
 */
@Slf4j
@Service
public class WebSocketMessageService extends BaseSocketService {
    /**
     * web消息用户在线列表
     */
    private Map<String, WebSocketMessageUser> messageUsers = new ConcurrentHashMap<>();

    /**
     * 建立连接处理
     *
     * @param socketSession
     * @param eventName
     * @param socketMessage
     */
    private void onOpenEventHandler(JcfkSocketSession socketSession, String eventName, SocketMessage socketMessage) {
        // 发布欢迎消息
        SocketMessage helloMessage = new SocketMessage();
        helloMessage.setMessageType("connection");
        helloMessage.setFunctionCode("onOpenReturn");
        helloMessage.setMessageContent("success");
        publish(helloMessage);
    }

    /**
     * 接收消息处理
     *
     * @param socketSession
     * @param eventName
     * @param socketMessage
     */
    private void receiveMessageHandler(JcfkSocketSession socketSession, String eventName, SocketMessage socketMessage) {
        switch (socketMessage.getFunctionCode()) {
            case "login":// 登录
                this.login(socketSession, socketMessage);
                break;
            case "ping":// 登录
                this.ping(socketSession, socketMessage);
                break;
        }
    }

    /**
     * 关闭连接处理
     *
     * @param socketSession
     * @param eventName
     * @param socketMessage
     */
    private void onCloseEventHandler(JcfkSocketSession socketSession, String eventName, SocketMessage socketMessage) {
        Object userId = socketSession.getTags().get("userId");
        if (userId != null) {
            messageUsers.remove(userId.toString());
        }
    }

    /**
     * 登录
     *
     * @param socketSession
     * @param socketMessage
     */
    public void login(JcfkSocketSession socketSession, SocketMessage socketMessage) {
        Map<String, Claim> maps = JwtUtil.parseToken(socketMessage.getToken());
        String userId = maps.get(SecurityConstants.USER_ID_KEY).asString();
        String username = maps.get(SecurityConstants.USER_NAME_KEY).asString();
        LoginInfo loginInfo = new LoginInfo(userId, socketMessage.getToken(),username);

        if (StrUtil.isNotEmpty(loginInfo.getToken()) && StrUtil.isNotEmpty(loginInfo.getUserId())) {
            // 添加web消息在线用户
            WebSocketMessageUser messageUser = new WebSocketMessageUser();
            messageUser.setToken(loginInfo.getToken());
            messageUser.setUserId(loginInfo.getUserId());
            messageUser.setUserName(loginInfo.getUserName());
            messageUser.setSocketSessionId(socketSession.getSession().getId());
            messageUsers.put(messageUser.getUserId(), messageUser);

            // 向websocket session添加用户主键
            socketSession.getTags().put("userId", messageUser.getUserId());
            sessionManager.update(socketSession.getSession().getId(), socketSession);

            // 发布欢迎消息
            SocketMessage helloMessage = new SocketMessage();
            helloMessage.setMessageType("login");
            helloMessage.setFunctionCode("loginReturn");
            helloMessage.setMessageContent("success");
            publish(helloMessage);
        }
    }

    /**
     * 登录
     *
     * @param socketSession
     * @param socketMessage
     */
    public void ping(JcfkSocketSession socketSession, SocketMessage socketMessage) {
        // 发布欢迎消息
        SocketMessage pingMessage = new SocketMessage();
        pingMessage.setMessageType("ping");
        pingMessage.setFunctionCode("pingReturn");
        pingMessage.setMessageContent("success");
        publish(pingMessage);
    }

    /**
     * 初始化
     *
     * @throws InterruptedException
     */
    @PostConstruct
    public void init() throws InterruptedException {
        this.addOnOpenHandler(this::onOpenEventHandler);
        this.addOnCloseHandler(this::onCloseEventHandler);
        this.addReceiveMessageHandler(this::receiveMessageHandler);
        super.init();

    }

    /**
     * 发送消息
     *
     * @param userid
     * @param message
     */
    public void sendMessage(String userid, SocketMessage message) {
        WebSocketMessageUser messageUser = this.messageUsers.get(userid);
        if (messageUser != null) {
            message.setSessionId(messageUser.getSocketSessionId());
            publish(message);
        }
    }

//    /**
//     * testBuild
//     */
//    public void testBuild(){
//        while(listening){
//            try {
//                //发布欢迎消息
//                SocketMessage helloMessage = new SocketMessage();
//                helloMessage.setMessageType("noticeMsg");
//                helloMessage.setFunctionCode("testsend");
//                helloMessage.setMessageContent(new Date().toString());
//                publish(helloMessage);
//
//                Thread.sleep(2000);
//            }
//            catch (Exception e){
//
//            }
//        }
//    }
}
